JavaScript 面试知识点总结
tip
本部分主要是GitHub博主: CavsZhouyou在复习 JavaScript 相关知识和一些相关面试题时所做的笔记,如果出现错误,希望大家指出!
目录
- 1. 介绍 js 的基本数据类型。
- 2. JavaScript 有几种类型的值?你能画一下他们的内存图吗?
- 3. 什么是堆?什么是栈?它们之间有什么区别和联系?
- 4. 内部属性 [[Class]] 是什么?
- 5. 介绍 js 有哪些内置对象?
- 6. undefined 与 undeclared 的区别?
- 7. null 和 undefined 的区别?
- 8. 如何获取安全的 undefined 值?
- 9. 说几条写 JavaScript 的基本规范?
- 10. JavaScript 原型,原型链? 有什么特点?
- 11. js 获取原型的方法?
- 12. 在 js 中不同进制数字的表示方式
- 13. js 中整数的安全范围是多少?
- 14. typeof NaN 的结果是什么?
- 15. isNaN 和 Number.isNaN 函数的区别?
- 16. Array 构造函数只有一个参数值时的表现?
- 17. 其他值到字符串的转换规则?
- 18. 其他值到数字值的转换规则?
- 19. 其他值到布尔类型的值的转换规则?
- 20. 和 [] 的 valueOf 和 toString 的结果是什么?
- 21. 什么是假值对象?
- 22. ~ 操作符的作用?
- 23. 解析字符串中的数字和将字符串强制类型转换为数字的返回结果都是数字,它们之间的区别是什么?
- 24. 操作符什么时候用于字符串的拼接?
- 25. 什么情况下会发生布尔值的隐式强制类型转换?
- 26. || 和 && 操作符的返回值?
- 27. Symbol 值的强制类型转换?
- 28. == 操作符的强制类型转换规则?
- 29. 如何将字符串转化为数字,例如 '12.3b'?
- 30. 如何将浮点数点左边的数每三位添加一个逗号,如 12000000.11 转化为『12,000,000.11』?
- 31. 常用正则 表达式
- 32. 生成随机数的各种方法?
- 33. 如何实现数组的随机排序?
- 34. javascript 创建对象的几种方式?
- 35. JavaScript 继承的几种实现方式?
- 36. 寄生式组合继承的实现?
- 37. Javascript 的作用域链?
- 38. 谈谈 This 对象的理解。
- 39. eval 是做什么的?
- 40. 什么是 DOM 和 BOM?
- 41. 写一个通用的事件侦听器函数。
- 42. 事件是什么?IE 与火狐的事件机制有什么区别? 如何阻止冒泡?
- 43. 三种事件模型是什么?
- 44. 事件委托是什么?
- 45. ["1", "2", "3"].map(parseInt) 答案是多少?
- 46. 什么是闭包,为什么要用它?
- 47. javascript 代码中的 "use strict"; 是什么意思 ? 使用它区别是什么?
- 48. 如何判断一个对象是否属于某个类?
- 49. instanceof 的作用?
- 50. new 操作符具体干了什么呢?如何实现?
- 51. Javascript 中,有一个函数,执行时对象查找时,永远不会去查找原型,这个函数是?
- 52. 对于 JSON 的了解?
- 53.
[].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})
能解释一下这段代码的意思吗? - 54. js 延迟加载的方式有哪些?
- 55. Ajax 是什么? 如何创建一个 Ajax?
- 56. 谈一谈浏览器的缓存机制?
- 57. Ajax 解决浏览器缓存问题?
- 58. 同步和异步的区别?
- 59. 什么是浏览器的同源政策?
- 60. 如何解决跨域问题?
- 61. 服务器代理转发时,该如何处理 cookie?
- 62. 简单谈一下 cookie ?
- 63. 模块化开发怎么做?
- 64. js 的几种模块规范?
- 65. AMD 和 CMD 规范的区别?
- 66. ES6 模块与 CommonJS 模块、AMD、CMD 的差异。
- 67. requireJS 的核心原理是什么?(如何动态加载的?如何避免多次加载的?如何 缓存的?)
- 68. JS 模块加载器的轮子怎么造,也就是如何实现一个模块加载器?
- 69. ECMAScript6 怎么写 class,为什么会出现 class 这种东西?
- 70. documen.write 和 innerHTML 的区别?
- 71. DOM 操作——怎样添加、移除、移动、复制、创建和查找节点?
- 72. innerHTML 与 outerHTML 的区别?
- 73. .call() 和 .apply() 的区别?
- 74. JavaScript 类数组对象的定义?
- 75. 数组和对象有哪些原生方法,列举一下?
- 76. 数组的 fill 方法?
- 77. [,,,] 的长度?
- 78. JavaScript 中的作用域与变量声明提升?
- 79. 如何编写高性能的 Javascript ?
- 80. 简单介绍一下 V8 引擎的垃圾回收机制
- 81. 哪些操作会造成内存泄漏?
- 82. 需求:实现一个页面操作不会整页刷新的网站,并且能在浏览器前进、后退时正确响应。给出你的技术实现方案?
- 83. 如何判断当前脚本运行在浏览器还是 node 环境中?(阿里)
- 84. 把 script 标签放在页面的最底部的 body 封闭之前和封闭之后有什么区别?浏览器会如何解析它们?
- 85. 移动端的点击事件的有延迟,时间是多久,为什么会有? 怎么解决这个延时?
- 86. 什么是“前端路由”?什么时候适合使用“前端路由”?“前端路由”有哪些优点和缺点?
- 87. 如何测试前端代码么? 知道 BDD, TDD, Unit Test 么? 知道怎么测试你的前端工程么(mocha, sinon, jasmin, qUnit..)?
- 88. 检测浏览器版本版本有哪些方式?
- 89. 什么是 Polyfill ?
- 90. 使用 JS 实现获取文件扩展名?
- 91. 介绍一下 js 的节流与防抖?
- 92. Object.is() 与原来的比较操作符 “===”、“==” 的区别?
- 93. escape,encodeURI,encodeURIComponent 有什么区别?
- 94. Unicode 和 UTF-8 之间的关系?
- 95. js 的事件循环是什么?
- 96. js 中的深浅拷贝实现?
- 97. 手写 call、apply 及 bind 函数
- 98. 函数柯里化的实现
- 99. 为什么 0.1 0.2 != 0.3?如何解决这个问题?
- 100. 原码、反码和补码的介绍
- 101. toPrecision 和 toFixed 和 Math.round 的区别?
- 102. 什么是 XSS 攻击?如何防范 XSS 攻击?
- 103. 什么是 CSP?
- 104. 什么是 CSRF 攻击?如何防范 CSRF 攻击?
- 105. 什么是 Samesite Cookie 属性?
- 106. 什么是点击劫持?如何防范点击劫持?
- 107. SQL 注入攻击?
- 108. 什么是 MVVM?比之 MVC 有什么区别?什么又是 MVP ?
- 109. vue 双向数据绑定原理?
- 110. Object.defineProperty 介绍?
- 111. 使用 Object.defineProperty() 来进行数据劫持有什么缺点?
- 112. 什么是 Virtual DOM?为什么 Virtual DOM 比原生 DOM 快?
- 113. 如何比较两个 DOM 树的差异?
- 114. 什么是 requestAnimationFrame ?
- 115. 谈谈你对 webpack 的看法
- 116. offsetWidth/offsetHeight,clientWidth/clientHeight 与 scrollWidth/scrollHeight 的区别?
- 117. 谈一谈你理解的函数式编程?
- 118. 异步编程的实现方式?
- 119. Js 动画与 CSS 动画区别及相应实现
- 120. get 请求传参长度的误区
- 121. URL 和 URI 的区别?
- 122. get 和 post 请求在缓存方面的区别
- 123. 图片的懒加载和预加载
- 124. mouseover 和 mouseenter 的区别?
- 125. js 拖拽功能的实现
- 126. 为什么使用 setTimeout 实现 setInterval?怎么模拟?
- 127. let 和 const 的注意点?
- 128. 什么是 rest 参数?
- 129. 什么是尾调用,使用尾调用有什么好处?
- 130. Symbol 类型的注意点?
- 131. Set 和 WeakSet 结构?
- 132. Map 和 WeakMap 结构?
- 133. 什么是 Proxy ?
- 134. Reflect 对象创建目的?
- 135. require 模块引入的查找方式?
- 136. 什么是 Promise 对象,什么是 Promises/A 规范?
- 137. 手写一个 Promise
- 138. 如何检测浏览器所支持的最小字体大小?
- 139. 怎么做 JS 代码 Error 统计?
- 140. 单例模式模式是什么?
- 141. 策略模式是什么?
- 142. 代理模式是什么?
- 143. 中介者模式是什么?
- 144. 适配器模式是什么?
- 145. 观察者模式和发布订阅模式有什么不同?
- 146. Vue 的生命周期是什么?
- 147. Vue 的各个生命阶段是什么?
- 148. Vue 组件间的参数传递方式?
- 149. computed 和 watch 的差异?
- 150. vue-router 中的导航钩子函数
- 151. router 的区别?
- 152. vue 常用的修饰符?
- 153. vue 中 key 值的作用?
- 154. computed 和 watch 区别?
- 155. keep-alive 组件有什么作用?
- 156. vue 中 mixin 和 mixins 区别?
- 157. 开发中常用的几种 Content-Type ?
- 158. 如何封装一个 javascript 的类型判断函数?
- 159. 如何判断一个对象是否为空对象?
- 160. 使用闭包实现每隔一秒打印 1,2,3,4
- 161. 手写一个 jsonp
- 162. 手写一个观察者模式?
- 163. EventEmitter 实现
- 164. 一道常被人轻视的前端 JS 面试题
- 165. 如何确定页面的可用性时间,什么是 Performance API?
- 166. js 中的命名规则
- 167. js 语句末尾分号是否可以省略?
- 168. Object.assign()
- 169. Math.ceil 和 Math.floor
- 170. js for 循环注意点
- 171. 一个列表,假设有 100000 个数据,这个该怎么办?
- 172. js 中倒计时的纠偏实现?
- 173. 进程间通信的方式?
- 174. 如何查找一篇英文文章中出现频率最高的单词?
- 175. ele.getElementsByClassName和ele.querySelectorAll的区别?
1. 介绍 js 的基本数据类型。
js 一共有六种基本数据类型,分别是 Undefined、Null、Boolean、Number、String,还有在 ES6 中新增的 Symbol 和 ES10 中新增的 BigInt 类型。
Symbol 代表创建后独一无二且不可变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突的问题。
BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。
2. JavaScript 有几种类型的值?你能画一下他们的内存图吗?
涉及知识点:
- 栈:原始数据类型(Undefined、Null、Boolean、Number、String)
- 堆:引用数据类型(对象、数组和函数)
两种类型的区别是:存储位置不同。
原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储。
引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在
栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实
体。
回答:
js 可以分为两种类型的值,一种是基本数据类型,一种是复杂数据类型。
基本数据类型....(参考1)
复杂数据类型指的是 Object 类型,所有其他的如 Array、Date 等数据类型都可以理解为 Object 类型的子类。
两种类型间的主要区别是它们的存储位置不同,基本数据类型的值直接保存在栈中,而复杂数据类型的值保存在堆中,通过使用在栈中
保存对应的指针来获取堆中的值。
详细资料可以参考: 《JavaScript 有几种类型的值?》 《JavaScript 有几种类型的值?能否画一下它们的内存图;》
3. 什么是堆?什么是栈?它们之间有什么区别和联系?
堆和栈的概念存在于数据结构中和操作系统内存中。
在数据结构中,栈中数据的存取方式为先进后出。而堆是一个优先队列,是按优先级来进行排序的,优先 级可以按照大小来规定。完全
二叉树是堆的一种实现方式。
在操作系统中,内存被分为栈区和堆区。
栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
堆区内存一般由程序员分配释放,若程序员不释放,程序结束时可能由垃圾回收机制回收。
详细资料可以参考: 《什么是堆?什么是栈?他们之间有什么区别和联系?》
4. 内部属 性 [[Class]] 是什么?
所有 typeof 返回值为 "object" 的对象(如数组)都包含一个内部属性 [[Class]](我们可以把它看作一个内部的分类,而非
传统的面向对象意义上的类)。这个属性无法直接访问,一般通过 Object.prototype.toString(..) 来查看。例如:
Object.prototype.toString.call( [1,2,3] );
// "[object Array]"
Object.prototype.toString.call( /regex-literal/i );
// "[object RegExp]"
// 我们自己创建的类就不会有这份特殊待遇,因为 toString() 找不到 toStringTag 属性时只好返回默认的 Object 标签
// 默认情况类的[[Class]]返回[object Object]
class Class1 {}
Object.prototype.toString.call(new Class1()); // "[object Object]"
// 需要定制[[Class]]
class Class2 {
get [Symbol.toStringTag]() {
return "Class2";
}
}
Object.prototype.toString.call(new Class2()); // "[object Class2]"
5. 介绍 js 有哪些 内置对象?
涉及知识点:
全局的对象( global objects )或称标准内置对象,不要和 "全局对象(global object)" 混淆。这里说的全局的对象是说在
全局作用域里的对象。全局作用域中的其他对象可以由用户的脚本创建或由宿主程序提供。
标准内置对象的分类
(1)值属性,这些全局属性返回一个简单值,这些值没有自己的属性和方法。
例如 Infinity、NaN、undefined、null 字面量
(2)函数属性,全局函数可以直接调用,不需要在调用时指定所属对象,执行结束后会将结果直接返回给调用者。
例如 eval()、parseFloat()、parseInt() 等
(3)基本对象,基本对象是定义或使用其他对象的基础。基本对象包括一般对象、函数对象和错误对象。
例如 Object、Function、Boolean、Symbol、Error 等
(4)数字和日期对象,用来表示数字、日期和执行数学计算的对象。
例如 Number、Math、Date
(5)字符串,用来表示和操作字符串的对象。
例如 String、RegExp
(6)可索引的集合对象,这些对象表示按照索引值来排序的数据集合,包括数组和类型数组,以及类数组结构的对象。例如 Array
(7)使用键的集合对象,这些集合对象在存储数据时会使用到键,支持按照插入顺序来迭代元素。
例如 Map、Set、WeakMap、WeakSet
(8)矢量集合,SIMD 矢量集合中的数据会被组织为一个数据序列。
例如 SIMD 等
(9)结构化数据,这些对象用来表示和操作结构化的缓冲区数据,或使用 JSON 编码的数据。
例如 JSON 等
(10)控制抽象对象
例如 Promise、Generator 等
(11)反射
例如 Reflect、Proxy
(12)国际化,为了支持多语言处理而加入 ECMAScript 的对象。
例如 Intl、Intl.Collator 等
(13)WebAssembly
(14)其他
例如 arguments
回答:
js 中的内置对象主要指的是在程序执行前存在全局作用域里的由 js 定义的一些全局值属性、函数和用来实例化其他对象的构造函
数对象。一般我们经常用到的如全局变量值 NaN、undefined,全局函数如 parseInt()、parseFloat() 用来实例化对象的构
造函数如 Date、Object 等,还有提供数学计算的单体内置对象如 Math 对象。
详细资料可以参考: 《标准内置对象的分类》 《JS 所有内置对象属性和方法汇总》
6. undefined 与 undeclared 的区别?
已在作用域中声明但还没有赋值的变量,是 undefined 的。相反,还没有在作用域中声明过的变量,是 undeclared 的。
对于 undeclared 变量的引用,浏览器会报引用错误,如 ReferenceError: b is not defined 。但是我们 可以使用 typ
eof 的安全防范机制来避免报错,因为对于 undeclared(或者 not defined )变量,typeof 会返回 "undefined"。
7. null 和 undefined 的区别?
首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。
undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefined,null
主要用于赋值给一些可能会返回对象的变量,作为初始化。
undefined 在 js 中不是一个保留字,这意味着我们可以使用 undefined 来作为一个变量名,这样的做法是非常危险的,它
会影响我们对 undefined 值的判断。但是我们可以通过一些方法获得安全的 undefined 值,比如说 void 0。
当我们对两种类型使用 typeof 进行判断的时候,Null 类型化会返回 “object”,这是一个历史遗留的问题。当我们使用双等
号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false。
详细资料可以参考: 《JavaScript 深入理解之 undefined 与 null》
8. 如何获取安全的 undefined 值?
因为 undefined 是一个标识符,所以可以被当作变量来使用和赋值,但是这样会影响 undefined 的正常判断。
表达式 void ___ 没有返回值,因此返回结果是 undefined。void 并不改变表达式的结果,只是让表达式不返回值。
按惯例我们用 void 0 来获得 undefined。
9. 说几条写 JavaScript 的基本规范?
在平常项目开发中,我们遵守一些这样的基本规范,比如说:
(1)一个函数作用域中所有的变量声明应该尽量提到函数首部,用一个 var 声明,不允许出现两个连续的 var 声明,声明时
如果变量没有值,应该给该变量赋值对应类型的初始值,便于他人阅读代码时,能够一目了然的知道变量对应的类型值。
(2)代码中出现地址、时间等字符串时需要使用常量代替。
(3)在进行比较的时候吧,尽量使用'===', '!=='代替'==', '!='。
(4)不要在内置对象的原型上添加方法,如 Array, Date。
(5)switch 语句必须带有 default 分支。
(6)for 循环必须使用大括号。
(7)if 语句必须使用大括号。
10. JavaScript 原型,原型链? 有什么特点?
在 js 中我们是使用构造函数来新建一个对象的,每一个构造函数的内部都有一个 prototype 属性值,这个属性值是一个对
象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法。当我们使用构造函数新建一个对象后,在这个对象的内部
将包含一个指针,这个指针指向构造函数的 prototype 属性对应的值,在 ES5 中这个指针被称为对象的原型。一般来说我们
是不应该能够获取到这个值的,但是现在浏览器中都实现了 __proto__ 属性来让我们访问这个属性,但是我们最好不要使用这
个属性,因为它不是规范中规定的。ES5 中新增了一个 Object.getPrototypeOf() 方法,我们可以通过这个方法来获取对
象的原型。
当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又
会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是 Object.prototype 所以这就
是我们新建的对象为什么能够使用 toString() 等方法的原因。
特点:
JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与
之相关的对象也会继承这一改变。
详细资料可以参 考: 《JavaScript 深入理解之原型与原型链》
11. js 获取原型的方法?
- p.__proto__
- p.constructor.prototype
- Object.getPrototypeOf(p)
12. 在 js 中不同进制数字的表示方式
-
以 0X、0x 开头的表示为十六进制。
-
以 0、0O、0o 开头的表示为八进制。
-
以 0B、0b 开头的表示为二进制格式。
13. js 中整数的安全范围是多少?
安全整数指的是,在这个范围内的整数转化为二 进制存储的时候不会出现精度丢失,能够被“安全”呈现的最大整数是 2^53 - 1,
即9007199254740991,在 ES6 中被定义为 Number.MAX_SAFE_INTEGER。最小整数是-9007199254740991,在 ES6 中
被定义为 Number.MIN_SAFE_INTEGER。
如果某次计算的结果得到了一个超过 JavaScript 数值范围的值,那么这个值会被自动转换为特殊的 Infinity 值。如果某次
计算返回了正或负的 Infinity 值,那么该值将无法参与下一次的计算。判断一个数是不是有穷的,可以使用 isFinite 函数
来判断。
14. typeof NaN 的结果是什么?
NaN 意指“不是一个数字”(not a number),NaN 是一个“警戒值”(sentinel value,有特殊用途的常规值),用于指出
数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果”。
typeof NaN; // "number"
NaN 是一个特殊值,它和自身不相等,是唯一一个非自反(自反,reflexive,即 x === x 不成立)的值。而 NaN != NaN
为 true。
15. isNaN 和 Number.isNaN 函数的区别?
函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会
返回 true ,会影响 NaN 的判断。
函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,这种方法对于 NaN 的判断更为
准确。
16. Array 构造函数只有一个参数值时的表现?
Array 构造函数只带一个数字参数的时候,该参数会被作为数组的预设长度(length),而非只充当数组中的一个元素。这样
创建出来的只是一个空数组,只不过它的 length 属性被设置成了指定的值。
构造函数 Array(..) 不要求必须带 new 关键字。不带时,它会被自动补上。
17. 其他值到字符串的转换规则?
规范的 9.8 节中定义了抽象操作 ToString ,它负责处理非字符串到字符串的强制类型转换。
(1)Null 和 Undefined 类型 ,null 转换为 "null",undefined 转换为 "undefined",
(2)Boolean 类型,true 转换为 "true",false 转换为 "false"。
(3)Number 类型的值直接转换,不过那些极小和极大的数字会使用指数形式。
(4)Symbol 类型的值直接转换,但是只允许显式强制类型转换,使用隐式强制类型转换会产生错误。
(5)对普通对象来说,除非自行定义 toString() 方法,否则会调用 toString()(Object.prototype.toString())
来返回内部属性 [[Class]] 的值,如"[object Object]"。如果对象有自己的 toString() 方法,字符串化时就会
调用该方法并使用其返回值。
18. 其他值到数字值的转换规则?
有时我们需要将非数字值当作数字来使用,比如数学运算。为此 ES5 规范在 9.3 节定义了抽象操作 ToNumber。
(1)Undefined 类型的值转换为 NaN。
(2)Null 类型的值转换为 0。
(3)Boolean 类型的值,true 转换为 1,false 转换为 0。
(4)String 类型的值转换如同使用 Number() 函数进行转换,如果包含非数字值则转换为 NaN,空字符串为 0。
(5)Symbol 类型的值不能转换为数字,会报错。
(6)对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。
为了将值转换为相应的基本类型值,抽象操作 ToPrimitive 会首先(通过内部操作 DefaultValue)检查该值是否有valueOf() 方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用 toString() 的返回值(如果存在)来进行强制类型转换。
如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。